home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 425_01 / tar / match.s < prev    next >
Text File  |  1980-07-23  |  14KB  |  382 lines

  1. /*
  2.  * Copyright (C) 1990-1993 Mark Adler, Richard B. Wales, Jean-loup Gailly,
  3.  * Kai Uwe Rommel and Igor Mandrichenko.
  4.  * Permission is granted to any individual or institution to use, copy, or
  5.  * redistribute this software so long as all of the original files are
  6.  * included, that it is not sold for profit, and that this copyright notice is
  7.  * retained.
  8.  *
  9.  * match.s by Jean-loup Gailly. Translated to 32 bit code by Kai Uwe Rommel.
  10.  * The 68020 version has been written by Francesco Potorti` <pot@cnuce.cnr.it>
  11.  * with adaptations by Carsten Steger <stegerc@informatik.tu-muenchen.de>,
  12.  * Andreas Schwab <schwab@lamothe.informatik.uni-dortmund.de> and
  13.  * Kristoffer Eriksson <ske@pkmab.se>
  14.  */
  15.  
  16. /* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix
  17.  * external symbols with an underline character '_'.
  18.  */
  19. #if defined(NO_UNDERLINE) || defined(SYSV)
  20. #  define _prev             prev
  21. #  define _window           window
  22. #  define _match_start      match_start
  23. #  define _prev_length      prev_length
  24. #  define _good_match       good_match
  25. #  define _nice_match       nice_match
  26. #  define _strstart         strstart
  27. #  define _max_chain_length max_chain_length
  28.  
  29. #  define _match_init       match_init
  30. #  define _longest_match    longest_match
  31. #endif
  32.  
  33. #ifdef DYN_ALLOC
  34.   error: DYN_ALLOC not yet supported in match.s
  35. #endif
  36.  
  37. #if defined(i386) || defined(_I386)
  38.  
  39. /* This version is for 386 Unix or OS/2 in 32 bit mode.
  40.  * Warning: it uses the AT&T syntax: mov source,dest
  41.  * This file is only optional. If you want to force the C version,
  42.  * add -DNO_ASM to CFLAGS in Makefile and set OBJA to an empty string.
  43.  * If you have reduced WSIZE in gzip.h, then change its value below.
  44.  * This version assumes static allocation of the arrays (-DDYN_ALLOC not used).
  45.  */
  46.  
  47.         .file   "match.S"
  48.  
  49. #define MAX_MATCH       258
  50. #define MAX_MATCH2      $128 /* MAX_MATCH/2-1 */
  51. #define MIN_MATCH       3
  52. #define    WSIZE        $32768
  53. #define MAX_DIST        WSIZE - MAX_MATCH - MIN_MATCH - 1
  54.  
  55.         .globl  _match_init
  56.         .globl  _longest_match
  57.  
  58.         .text
  59.  
  60. _match_init:
  61.         ret
  62.  
  63. /*-----------------------------------------------------------------------
  64.  * Set match_start to the longest match starting at the given string and
  65.  * return its length. Matches shorter or equal to prev_length are discarded,
  66.  * in which case the result is equal to prev_length and match_start is
  67.  * garbage.
  68.  * IN assertions: cur_match is the head of the hash chain for the current
  69.  *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
  70.  */
  71.  
  72. _longest_match: /* int longest_match(cur_match) */
  73.  
  74. #define cur_match   20(%esp)
  75.      /* return address */               /* esp+16 */
  76.         push    %ebp                    /* esp+12 */
  77.         push    %edi                    /* esp+8  */
  78.         push    %esi                    /* esp+4  */
  79.         push    %ebx                    /* esp    */
  80.  
  81. /*
  82.  *      match        equ esi
  83.  *      scan         equ edi
  84.  *      chain_length equ ebp
  85.  *      best_len     equ ebx
  86.  *      limit        equ edx
  87.  */
  88.         mov     cur_match,%esi
  89.         mov     _max_chain_length,%ebp /* chain_length = max_chain_length */
  90.         mov     _strstart,%edi
  91.         mov     %edi,%edx
  92.         sub     MAX_DIST,%edx          /* limit = strstart-MAX_DIST */
  93.         jae     limit_ok
  94.         sub     %edx,%edx              /* limit = NIL */
  95. limit_ok:
  96.         add     $2+_window,%edi        /* edi = offset(window+strstart+2) */
  97.         mov     _prev_length,%ebx      /* best_len = prev_length */
  98.         movw    -3(%ebx,%edi),%ax      /* ax = scan[best_len-1..best_len] */
  99.         movw    -2(%edi),%cx           /* cx = scan[0..1] */
  100.         cmp     _good_match,%ebx       /* do we have a good match already? */
  101.         jb      do_scan
  102.         shr     $2,%ebp                /* chain_length >>= 2 */
  103.         jmp     do_scan
  104.  
  105.         .align  4
  106. long_loop:
  107. /* at this point, edi == scan+2, esi == cur_match */
  108.         movw    -3(%ebx,%edi),%ax       /* ax = scan[best_len-1..best_len] */
  109.         movw     -2(%edi),%cx           /* cx = scan[0..1] */
  110. short_loop:
  111. /*
  112.  * at this point, di == scan+2, si == cur_match,
  113.  * ax = scan[best_len-1..best_len] and cx = scan[0..1]
  114.  */
  115.         and     WSIZE-1, %esi
  116.         movw    _prev(%esi,%esi),%si    /* cur_match = prev[cur_match] */
  117.                                         /* top word of esi is still 0 */
  118.         cmp     %edx,%esi               /* cur_match <= limit ? */
  119.         jbe     the_end
  120.         dec     %ebp                    /* --chain_length */
  121.         jz      the_end
  122. do_scan:
  123.         cmpw    _window-1(%ebx,%esi),%ax/* check match at best_len-1 */
  124.         jne     short_loop
  125.         cmpw    _window(%esi),%cx       /* check min_match_length match */
  126.         jne     short_loop
  127.  
  128.         lea     _window+2(%esi),%esi    /* si = match */
  129.         mov     %edi,%eax               /* ax = scan+2 */
  130.         mov     MAX_MATCH2,%ecx         /* scan for at most MAX_MATCH bytes */
  131.         rep;    cmpsw                   /* loop until mismatch */
  132.         je      maxmatch                /* match of length MAX_MATCH? */
  133. mismatch:
  134.         movb    -2(%edi),%cl        /* mismatch on first or second byte? */
  135.         subb    -2(%esi),%cl        /* cl = 0 if first bytes equal */
  136.         xchg    %edi,%eax           /* edi = scan+2, eax = end of scan */
  137.         sub     %edi,%eax           /* eax = len */
  138.         sub     %eax,%esi           /* esi = cur_match + 2 + offset(window) */
  139.         sub     $2+_window,%esi     /* esi = cur_match */
  140.         subb    $1,%cl              /* set carry if cl == 0 (cannot use DEC) */
  141.         adc     $0,%eax             /* eax = carry ? len+1 : len */
  142.         cmp     %ebx,%eax           /* len > best_len ? */
  143.         jle     long_loop
  144.         mov     %esi,_match_start       /* match_start = cur_match */
  145.         mov     %eax,%ebx               /* ebx = best_len = len */
  146.         cmp     _nice_match,%eax        /* len >= nice_match ? */
  147.         jl      long_loop
  148. the_end:
  149.         mov     %ebx,%eax               /* result = eax = best_len */
  150.         pop     %ebx
  151.         pop     %esi
  152.         pop     %edi
  153.         pop     %ebp
  154.         ret
  155. maxmatch:
  156.         cmpsb
  157.         jmp     mismatch
  158.  
  159. #else
  160.  
  161. /* ======================== 680x0 version ================================= */
  162.  
  163. #if defined(m68k)||defined(mc68k)||defined(__mc68000__)||defined(__MC68000__)
  164. #  ifndef mc68000
  165. #    define mc68000
  166. #  endif
  167. #endif
  168.  
  169. #if defined(__mc68020__) || defined(__MC68020__) || defined(sysV68)
  170. #  ifndef mc68020
  171. #    define mc68020
  172. #  endif
  173. #endif
  174.  
  175. #if defined(mc68020) || defined(mc68000)
  176.  
  177. #if (defined(mc68020) || defined(NeXT)) && !defined(UNALIGNED_OK)
  178. #  define UNALIGNED_OK
  179. #endif
  180.  
  181. #ifdef sysV68  /* Try Motorola Delta style */
  182.  
  183. #  define GLOBAL(symbol)        global  symbol
  184. #  define TEXT                  text
  185. #  define FILE(filename)        file    filename
  186. #  define invert_maybe(src,dst) dst,src
  187. #  define imm(data)             &data
  188. #  define reg(register)         %register
  189.  
  190. #  define addl                  add.l
  191. #  define addql                 addq.l
  192. #  define blos                  blo.b
  193. #  define bhis                  bhi.b
  194. #  define bras                  bra.b
  195. #  define clrl                  clr.l
  196. #  define cmpmb                 cmpm.b
  197. #  define cmpw                  cmp.w
  198. #  define cmpl                  cmp.l
  199. #  define lslw                  lsl.w
  200. #  define lsrl                  lsr.l
  201. #  define movel                 move.l
  202. #  define movew                 move.w
  203. #  define moveb                 move.b
  204. #  define moveml                movem.l
  205. #  define subl                  sub.l
  206. #  define subw                  sub.w
  207. #  define subql                 subq.l
  208.  
  209. #  define IndBase(bd,An)        (bd,An)
  210. #  define IndBaseNdxl(bd,An,Xn) (bd,An,Xn.l)
  211. #  define IndBaseNdxw(bd,An,Xn) (bd,An,Xn.w)
  212. #  define predec(An)            -(An)
  213. #  define postinc(An)           (An)+
  214.  
  215. #else /* default style (Sun 3, NeXT, Amiga, Atari) */
  216.  
  217. #  define GLOBAL(symbol)